home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / imlib / jwindow.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  14KB  |  606 lines

  1. #include "video.hpp"
  2. #include "image.hpp"
  3. #include "event.hpp"
  4. #include "filter.hpp"
  5. #include "event.hpp"
  6. #include "jwindow.hpp"
  7.  
  8. int jw_left=5,jw_right=5,jw_top=15,jw_bottom=5;
  9.  
  10. int frame_top() { return jw_top; }
  11. int frame_bottom() { return jw_bottom; }
  12. int frame_left() { return jw_left; }
  13. int frame_right() { return jw_right; }
  14.  
  15. ifield::~ifield() { ; }
  16.  
  17. void set_frame_size(int x)
  18. {  
  19.   if (x<1) x=1;
  20.   jw_left=x;
  21.   jw_right=x;
  22.   jw_top=10+x;
  23.   jw_bottom=x;
  24. }
  25.  
  26.  // true if a window lies in this area
  27. int window_manager::window_in_area(int x1, int y1, int x2, int y2)
  28. {
  29.   for (jwindow *f=first;f;f=f->next) 
  30.     if (f->x<=x2 && f->y<=y2 && f->x+f->l-1>=x1 && f->y+f->h-1>=y1)
  31.       return 1;
  32.   return 0;
  33. }
  34.  
  35. void window_manager::grab_focus(jwindow *j)
  36. { grab=j; }
  37.  
  38. void window_manager::release_focus()
  39. { grab=NULL; }
  40.  
  41.  
  42. void window_manager::close_window(jwindow *j)
  43. {
  44.   jwindow *k;
  45.   if (grab==j) grab=NULL;
  46.   if (state==dragging && j==drag_window)  // close the window we were dragging
  47.     state=inputing;
  48.  
  49.   if (j==first)
  50.     first=first->next;
  51.   else
  52.   {
  53.     for (k=first;k->next!=j;k=k->next)
  54.       k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  55.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  56.     k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  57.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  58.     k->next=j->next;
  59.   }
  60.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  61.   delete j;
  62. }
  63.  
  64. void window_manager::hide_windows()
  65. {
  66.   jwindow *p;
  67.   for (p=first;p;p=p->next)
  68.   {
  69.     if (!p->property.hidden)
  70.     {
  71.       p->property.hidden=1;
  72.       screen->add_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  73.     }
  74.   }
  75. }
  76.  
  77. void window_manager::show_windows()
  78. {
  79.   jwindow *p;
  80.   for (p=first;p;p=p->next)
  81.     if (p->property.hidden)
  82.       show_window(p);      
  83. }
  84.  
  85. void window_manager::hide_window(jwindow *j)
  86. {
  87.   jwindow *k;
  88.   if (j==first)
  89.     first=first->next;
  90.   else
  91.   {
  92.     for (k=first;k->next!=j;k=k->next)
  93.       k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  94.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  95.     k->screen->add_dirty(j->x-k->x,j->y-k->y, 
  96.                    j->x+j->l-1-k->x,j->y+j->h-1-k->y);
  97.     k->next=j->next;
  98.   }
  99.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  100.   j->property.hidden=1;
  101. }
  102.  
  103. void window_manager::show_window(jwindow *j)
  104. {
  105.   if (j->property.hidden)
  106.   {
  107.     j->property.hidden=0;
  108.     j->screen->add_dirty(0,0,j->l-1,j->h-1);
  109.   }
  110. }
  111.  
  112. void window_manager::get_event(event &ev)
  113. {
  114.   jwindow *j;
  115.   eh->get_event(ev);
  116.   if (ev.type==EV_KEY)
  117.     key_state[ev.key]=1;
  118.   else if (ev.type==EV_KEYRELEASE)
  119.     key_state[ev.key]=0;
  120.  
  121.   if (state==inputing)
  122.   {
  123.     for (ev.window=NULL,j=first;j;j=j->next)
  124.       if (!j->property.hidden && ev.mouse_move.x>=j->x && ev.mouse_move.y>=j->y &&
  125.           ev.mouse_move.x<j->x+j->l && ev.mouse_move.y<j->y+j->h)
  126.         ev.window=j;
  127.  
  128.     if (!ev.window && grab) ev.window=grab;
  129.  
  130.     if (ev.window)
  131.     {
  132.       int closew=0,movew=0;
  133.  
  134.       if ((ev.type==EV_MOUSE_BUTTON && ev.mouse_button==1 && ev.window &&
  135.        ev.mouse_move.x>=ev.window->x && ev.mouse_move.y>=ev.window->y &&
  136.        ev.mouse_move.x<ev.window->x+ev.window->l && ev.mouse_move.y<ev.window->y+ev.window->y1()))
  137.       {
  138.     if (ev.mouse_move.x-ev.window->x<11) closew=1;
  139.     else if (ev.window->property.moveable) movew=1;
  140.       } else if (grab)
  141.         ev.window=grab;
  142.  
  143.       if (ev.type==EV_KEY && ev.key==JK_ESC)
  144.         closew=1;
  145.  
  146.       
  147.     
  148.       if (closew)
  149.         ev.type=EV_CLOSE_WINDOW;
  150.       else if (movew)
  151.       {    
  152.     int red=0;
  153.     if (ev.window==first)       // see if we need to raise the window
  154.     {
  155.       first=first->next;
  156.       if (first)
  157.         red=1;
  158.     }
  159.     else
  160.     {
  161.       jwindow *last=first;
  162.       for (;last->next!=ev.window;last=last->next);
  163.       if (ev.window->next)
  164.         red=1;
  165.       last->next=ev.window->next;
  166.     }
  167.     if (!first)
  168.       first=ev.window;
  169.     else
  170.     {
  171.       jwindow *last=first;
  172.       for (;last->next;last=last->next);
  173.       last->next=ev.window;
  174.     }
  175.     ev.window->next=NULL;
  176.     if (red)
  177.     {
  178.       jwindow *j=ev.window,*p;
  179. /*      screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  180.       for (p=first;p!=j;p=p->next)
  181.         p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);*/
  182.       j->screen->add_dirty(0,0,j->l-1,j->h-1);
  183.       flush_screen();
  184.     }
  185.  
  186.         state=dragging;
  187.         drag_window=ev.window;
  188.         drag_mousex=ev.window->x-ev.mouse_move.x;
  189.         drag_mousey=ev.window->y-ev.mouse_move.y;
  190.         ev.type=EV_SPURIOUS;
  191.       } else if (ev.window)
  192.         ev.window->inm->handle_event(ev,ev.window,this);
  193.     }
  194.   } else if (state==dragging)
  195.   {
  196.     ev.window=drag_window;
  197.     if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button==0)  // user released the mouse
  198.     {
  199.       state=inputing;
  200.       ev.type=EV_SPURIOUS;
  201.     } else if (ev.type==EV_MOUSE_MOVE)
  202.     {
  203.        move_window(drag_window,ev.mouse_move.x+drag_mousex,ev.mouse_move.y+drag_mousey);
  204.        flush_screen();
  205.        ev.type=EV_DRAG_WINDOW;
  206.        ev.window_position.x=ev.mouse_move.x+drag_mousex;
  207.        ev.window_position.y=ev.mouse_move.y+drag_mousey;
  208.     }
  209.   } 
  210.   if (ev.type==EV_REDRAW)
  211.   {
  212.     for (j=first;j;j=j->next) 
  213.        j->screen->add_dirty(ev.redraw.x1-j->x,ev.redraw.y1-j->y,
  214.              ev.redraw.x2-j->x,ev.redraw.y2-j->y);
  215.     screen->add_dirty(ev.redraw.x1,ev.redraw.y1,ev.redraw.x2,ev.redraw.y2);
  216.     flush_screen();
  217.     ev.type=EV_SPURIOUS;   // we took care of this one by ourselves.
  218.   }
  219. }
  220.  
  221. void jwindow::resize(int L, int H)
  222. {
  223.   screen->change_size(L,H);
  224.   l=L; h=H;
  225. }
  226.  
  227. void window_manager::resize_window(jwindow *j, int l, int h)
  228. {
  229.   jwindow *p;
  230.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  231.   for (p=first;p!=j;p=p->next)
  232.     p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);
  233.   j->resize(l,h);
  234.   if (!frame_suppress)
  235.   j->redraw(hi,med,low,frame_font());
  236. }
  237.  
  238. void window_manager::move_window(jwindow *j, int x, int y)
  239. {
  240.   jwindow *p;
  241.   screen->add_dirty(j->x,j->y,j->x+j->l-1,j->y+j->h-1);
  242.   for (p=first;p!=j;p=p->next)
  243.     p->screen->add_dirty(j->x-p->x,j->y-p->y,j->x+j->l-1-p->x,j->y+j->h-1-p->y);
  244.   j->x=x;
  245.   j->y=y;
  246.   j->screen->add_dirty(0,0,j->l-1,j->h-1);
  247. }
  248.  
  249. window_manager::window_manager(image *Screen, palette *Pal, int Hi, 
  250.                                int Med, int Low, JCFont *Font)
  251. {
  252.   screen=Screen; hi=Hi; low=Low; med=Med; first=NULL; pal=Pal; grab=NULL;
  253.   bk=pal->find_closest(0,0,0);
  254.   state=inputing; fnt=Font;  wframe_fnt=Font;
  255.   memset(key_state,0,sizeof(key_state));
  256.   eh=new event_handler(screen,pal);
  257.   frame_suppress=0;
  258. }
  259.  
  260. jwindow *window_manager::new_window(int x, int y, int l, int h, ifield *fields, char *Name)
  261. {
  262.   if (x>screen->width()-4) x=screen->width()-25;
  263.   if (y>screen->height()-4) y=screen->height()-10;
  264.   
  265.   jwindow *j=new jwindow(x,y,l,h,this,fields,Name),*k;
  266.   j->property.hidden=0;
  267.   if (!first)
  268.     first=j;
  269.   else
  270.   {
  271.     k=first;
  272.     while (k->next) k=k->next;
  273.     k->next=j;
  274.     j->next=NULL;
  275.   }
  276.   if (!frame_suppress)
  277.     j->redraw(hi,med,low,frame_font());
  278.   return j;
  279. }
  280.  
  281. void window_manager::flush_screen()
  282. {
  283.   jwindow *p,*q;
  284.  
  285.   int mx,my,but;
  286.   image *mouse_pic,*mouse_save;
  287.   
  288.   if (has_mouse())
  289.   {    
  290.     mouse_pic=eh->mouse_sprite()->visual;
  291.     mouse_save=eh->mouse_sprite()->save;
  292.     mx=eh->mouse->drawx();
  293.     my=eh->mouse->drawy();
  294.  
  295.     screen->put_part(mouse_save,0,0,mx,my,mx+mouse_pic->width()-1,my+mouse_pic->height()-1);
  296.     mouse_pic->put_image(screen,mx,my,1);
  297.   }
  298.   
  299.   for (p=first;p;p=p->next)
  300.     if (!p->property.hidden)
  301.        screen->delete_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  302.   update_dirty(screen);
  303.  
  304.   if (has_mouse())
  305.     mouse_save->put_image(screen,mx,my);
  306.  
  307.  
  308.   for (p=first;p;p=p->next)
  309.   {
  310.     if (!p->property.hidden)
  311.     {
  312.       if (has_mouse())
  313.       {      
  314.     p->screen->put_part(mouse_save,0,0,mx-p->x,my-p->y,
  315.                 mx-p->x+mouse_pic->width()-1,
  316.                 my-p->y+mouse_pic->height()-1);
  317.     if (has_mouse())
  318.         mouse_pic->put_image(p->screen,mx-p->x,my-p->y,1);
  319.       }
  320.       
  321.  
  322. //      screen->delete_dirty(p->x,p->y,p->x+p->l-1,p->y+p->h-1);
  323.       for (q=p->next;q;q=q->next)
  324.         if (!q->property.hidden)
  325.           p->screen->delete_dirty(q->x-p->x,
  326.                               q->y-p->y,
  327.                               q->x+q->l-1-p->x,
  328.                               q->y+q->h-1-p->y);
  329.       update_dirty(p->screen,p->x,p->y);
  330.       if (has_mouse())
  331.          mouse_save->put_image(p->screen,mx-p->x,my-p->y,0);
  332.     }
  333.   }
  334. }
  335.  
  336. void jwindow::set_moveability(int x)
  337. {
  338.   property.moveable=x;
  339. }
  340.  
  341. jwindow::jwindow(int X, int Y, int L, int H, window_manager *wm, ifield *fields, char *Name)
  342. {
  343.   ifield *i;
  344.   int x1,y1,x2,y2;
  345.   l=0; h=0; 
  346.   property.moveable=1;
  347.   if (fields)
  348.     for (i=fields;i;i=i->next)
  349.     {
  350.       i->area(x1,y1,x2,y2,wm);
  351.       if ((int)y2>(int)h) 
  352.         h=y2+1;
  353.       if ((int)x2>(int)l) 
  354.         l=x2+1;
  355.     }
  356.   else { l=2; h=2; }
  357.  
  358.   if (L<=0) { l=l-L; } else l=L+jw_left;
  359.   if (H<=0) { h=h-H; } else h=H+jw_top;
  360.  
  361.  if (Y<0) y=yres-h+Y-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM-1; else y=Y;
  362.  if (X<0) x=xres-l+X-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT-1; else x=X;
  363.  
  364.   backg=wm->medium_color();
  365.   l+=WINDOW_FRAME_RIGHT; h+=WINDOW_FRAME_BOTTOM;
  366. //  if (!fields) { l+=WINDOW_FRAME_LEFT; h+=WINDOW_FRAME_TOP; }
  367.  
  368.   if (l<18) l=18;
  369.   if (h<12) h=12;
  370.   screen=new image(l,h,NULL,2);
  371.   l=screen->width();
  372.   h=screen->height();
  373.   screen->clear(backg);
  374.   next=NULL;
  375.   inm=new input_manager(screen,wm,fields);
  376.   if (Name==NULL)
  377.     name=strcpy((char *)jmalloc(strlen(" ")+1,"jwindow::window name")," ");  
  378.   else
  379.     name=strcpy((char *)jmalloc(strlen(Name)+1,"jwindow::window name"),Name);
  380. }
  381.  
  382. void jwindow::local_close() { ; }
  383.  
  384. void jwindow::redraw(int hi, int med, int low, JCFont *fnt)
  385. {
  386.   if (jw_right>=3)
  387.     screen->rectangle(0,0,l-3,h-3,low);
  388.   if (jw_right>=2)
  389.     screen->rectangle(1,1,l-2,h-2,med);
  390.   if (jw_right>=1)
  391.     screen->rectangle(2,2,l-1,h-1,hi);
  392.  
  393.  
  394.   
  395.   screen->wiget_bar(0,0,l-1,8,hi,med,low);
  396.   screen->line(1,1,l-2,1,low);
  397.   screen->line(1,3,l-2,3,low);
  398.   screen->line(1,5,l-2,5,low);
  399.   screen->line(1,7,l-2,7,low);
  400.  
  401.   screen->wiget_bar(4,3,10,5,hi,med,low);
  402.   screen->rectangle(3,2,11,6,0);  
  403.  
  404.   screen->line(0,8,l-1,8,0);
  405.   if (jw_right>=1)
  406.     screen->wiget_bar(0,9,l-1,h-1,hi,med,low);  
  407.     screen->wiget_bar(0,9,l-1,h-1,hi,med,low);
  408.   if (jw_right>=2)
  409.     screen->wiget_bar(4,13,l-jw_right,h-jw_right,low,med,hi);
  410.  
  411.  
  412.   if (name && name[0] && (name[0]!=' ' || name[1]))
  413.   {
  414.     short cx1,cy1,cx2,cy2;
  415.     screen->get_clip(cx1,cy1,cx2,cy2);
  416.     screen->set_clip(14,1,l-2,WINDOW_FRAME_TOP-4);
  417.     screen->bar(14,1,14+fnt->width()*strlen(name),15-8,med);
  418.     fnt->put_string(screen,14,1,name,low);  
  419.     screen->set_clip(cx1,cy1,cx2,cy2);
  420.   }
  421.   
  422.   screen->bar(x1(),y1(),x2(),y2(),backg);
  423.   inm->redraw();
  424. }
  425.  
  426.  
  427. ifield *input_manager::unlink(int id)     // unlinks ID from fields list and return the pointer to it
  428.   for (ifield *i=first,*last;i;i=i->next)
  429.   {
  430.     if (i->id==id) 
  431.     {
  432.       if (i==first)
  433.     first=first->next;
  434.       else
  435.         last->next=i->next;
  436.       if (active==i)
  437.         active=first;
  438.       return i;
  439.     }
  440.     ifield *x=i->unlink(id);
  441.     if (x) return x;
  442.     last=i;
  443.   }
  444.   return NULL;   // no such id
  445. }
  446.  
  447. input_manager::~input_manager() 
  448. { ifield *i; 
  449.   while (first) 
  450.   { i=first; 
  451.     first=first->next; 
  452.     delete i; 
  453.   } 
  454.  
  455. void input_manager::clear_current()
  456. {
  457.   if (active)
  458.     active->draw(0,screen,wm);
  459.  
  460.   active=NULL;
  461. }
  462.  
  463. void input_manager::handle_event(event &ev, jwindow *j, window_manager *wm)
  464. {
  465.   ifield *i,*in_area=NULL;
  466.   int x1,y1,x2,y2;
  467.   if (j)
  468.   {
  469.     ev.mouse_move.x-=j->x;
  470.     ev.mouse_move.y-=j->y;
  471.     cur=j;
  472.   }
  473.  
  474.   if (!grab)
  475.   {
  476.     if ((ev.type==EV_MOUSE_BUTTON && ev.mouse_button==1) || ev.type==EV_MOUSE_MOVE)
  477.     {
  478.       for (i=first;i;i=i->next)
  479.       {
  480.     i->area(x1,y1,x2,y2,wm);
  481.     if (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
  482.         ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2)
  483.         in_area=i;
  484.       }
  485.       if (in_area!=active && (no_selections_allowed || (in_area && in_area->selectable())))
  486.       {
  487.     if (active)
  488.           active->draw(0,screen,wm);
  489.  
  490.     active=in_area; 
  491.  
  492.     if (active)
  493.       active->draw(1,screen,wm);
  494.       }
  495.     } 
  496.     if (ev.type==EV_KEY && ev.key==JK_TAB && active)
  497.     { 
  498.       active->draw(0,screen,wm);
  499.       do
  500.       {
  501.     active=active->next;
  502.     if (!active) active=first;
  503.       } while (active && !active->selectable());
  504.       active->draw(1,screen,wm);
  505.     }
  506.   } else active=grab;
  507.  
  508.   if (active)
  509.   {
  510.     if (ev.type!=EV_MOUSE_MOVE && ev.type!=EV_MOUSE_BUTTON)
  511.       active->handle_event(ev,screen,wm,this);
  512.     else
  513.     {
  514.       active->area(x1,y1,x2,y2,wm);
  515.       if (grab || (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
  516.           ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2))
  517.       {
  518.     if (j)
  519.       active->handle_event(ev,screen,wm,j->inm);
  520.     else active->handle_event(ev,screen,wm,this);
  521.       }
  522.     }
  523.   }
  524.  
  525.   if (j)
  526.   {
  527.     ev.mouse_move.x+=j->x;
  528.     ev.mouse_move.y+=j->y;
  529.   }
  530. }
  531.  
  532. void input_manager::allow_no_selections()
  533. {
  534.   no_selections_allowed=1;
  535. }
  536.  
  537. void input_manager::redraw()
  538. {
  539.   ifield *i;
  540.   for (i=first;i;i=i->next)
  541.     i->draw_first(screen,wm);
  542.   if (active)
  543.     active->draw(1,screen,wm);
  544. }
  545.  
  546. input_manager::input_manager(image *Screen, window_manager *WM, ifield *First)
  547. {
  548.   no_selections_allowed=0;
  549.   cur=NULL;
  550.   grab=NULL;
  551.   screen=Screen;
  552.   wm=WM;
  553.   active=first=First;
  554.   while (active && !active->selectable()) active=active->next;
  555.   redraw();
  556. }
  557.  
  558. void input_manager::grab_focus(ifield *i)
  559. { grab=i; 
  560.   if (cur)
  561.     wm->grab_focus(cur);
  562. }
  563.  
  564. void input_manager::release_focus()
  565. { grab=NULL; 
  566.   if (cur)
  567.     wm->release_focus();
  568. }
  569.  
  570. void input_manager::remap(filter *f)
  571. {
  572.   for (ifield *i=first;i;i=i->next)
  573.    i->remap(f);
  574.   redraw();
  575. }
  576.  
  577. void input_manager::add(ifield *i) 
  578. { ifield *f=first;
  579.   if (i->selectable())
  580.   {
  581.     if (!f)
  582.       first=i;
  583.     else
  584.     {
  585.       while (f->next) f=f->next;
  586.       f->next=i; 
  587.     }
  588.   }
  589. }
  590.  
  591. ifield *input_manager::get(int id)
  592. {
  593.   ifield *f;
  594.   for (f=first;f;f=f->next)
  595.   {
  596.     ifield *ret=f->find(id);
  597.     if (ret) return ret;
  598.   }
  599.   return NULL;
  600. }
  601.  
  602.  
  603.  
  604.